package main

import (
	"encoding/xml"
	"fmt"
	"net/http"
	"net/url"
	"regexp"
	"time"
)

const (
	googleCodesiteURL = "http://code.google.com/"

	googleCodesiteTimeLayout = "Wed Sep 28 15:04:05 2006"

	ActivityGoogleCodesiteReporte = "GoogleCodesiteReport"
	ActivityGoogleCodesiteChange  = "GoogleCodesiteChange"
	ActivityGoogleCodesiteComment = "GoogleCodesiteComment"
	ActivityGoogleCodesiteCommit  = "GoogleCodesiteCommit"
	ActivityGoogleCodesiteOther   = "GoogleCodesiteOther"
)

var (
	activityGoogleCodesiteRegexp = regexp.MustCompile(`\((.*)\)(.*) (reported|changed|commented|commented|commited|pushed)( on)?$`)
)

type GoogleCodesiteLink struct {
	Rel  string "attr"
	Type string "attr"
	Href string "attr"
	Text string "chardata"
}

type GoogleCodesiteCategory struct {
	Term string "attr"
}

type GoogleCodesiteEntry struct {
	Updated    string
	Id         string
	Link       GoogleCodesiteLink
	Title      string
	AuthorName string "author>name"
	Category   GoogleCodesiteCategory
	Content    string
}

type GoogleCodesiteAtom struct {
	Updated string
	Entry   []GoogleCodesiteEntry
}

type GoogleCodesiteActivity struct {
	Time         *time.Time // title attr in span date classs
	ProjectPath  string     // a href="/p/..."
	IssueLink    string     // ot-issue-link href=
	Issue        string     // issue number
	Title        string     // (....) status ..
	ActivityType string     // reported, changed, ..
	Detail       string
}

type GoogleCodesite struct {
	*url.URL
}

func NewGoogleCodesite(path string) *GoogleCodesite {
	url_, _ := url.Parse(path)
	return &GoogleCodesite{URL: url_}
}

func parseGoogleCodesiteTitle(title string) (project, issue GoogleCodesiteLink, summary, activityType string) {
	var t struct {
		A    []GoogleCodesiteLink
		Text string "chardata"
	}
	err := xml.Unmarshal([]byte("<p>"+title+"</p>"), &t)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", t)
	if len(t.A) >= 2 {
		project = t.A[0]
		issue = t.A[1]
	}
	if m := activityGoogleCodesiteRegexp.FindStringSubmatch(t.Text); m != nil {
		summary = m[1]
		switch m[3] {
		case "reported":
			activityType = ActivityGoogleCodesiteReporte
		case "changed":
			activityType = ActivityGoogleCodesiteChange
		case "commented":
			activityType = ActivityGoogleCodesiteComment
		case "committed":
			activityType = ActivityGoogleCodesiteCommit
		default:
			activityType = ActivityGoogleCodesiteOther
		}
	} else {
		summary = t.Text
		activityType = ActivityGoogleCodesiteOther
	}
	return
}

func (gc *GoogleCodesite) fetchUser(c *http.Client, user string) error {
	resp, err := c.Get(fmt.Sprintf("%s/feeds/u/%s/updates/user/basic", gc.URL.String(), user))
	if err != nil {
		return err
	}
	var atom GoogleCodesiteAtom
	err = xml.NewDecoder(resp.Body).Decode(&atom)
	if err != nil {
		return err
	}
	for _, entry := range atom.Entry {
		update, _ := time.Parse(time.RFC3339, entry.Updated)
		id := entry.Id
		link := ""
		if entry.Link.Rel == "alternate" {
			link = entry.Link.Href
		}
		title := entry.Title
		authorName := entry.AuthorName
		category := entry.Category
		content := entry.Content

		fmt.Printf("update %s\nid %s\nlink %s\ntitle %s\nauthor %s\ncategory %s\ncontent %s\n\n", update, id, link, title, authorName, category, content)
		project, issue, summary, atype := parseGoogleCodesiteTitle(title)
		fmt.Printf("----------------------------------------------------------------\n%s\n%s\n%s\n%s\n================================================================\n", project, issue, summary, atype)
	}
	return nil
}

func main() {
	gc := NewGoogleCodesite(googleCodesiteURL)
	err := gc.fetchUser(&http.Client{}, "kinuko@chromium.org")
	if err != nil {
		panic(err)
	}
}
